﻿#region using

using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using OpenComposite.Base;
using OpenComposite.HumanActivity.Contracts;

#endregion

namespace OpenComposite.UserAccess
{
	/// <summary>
	/// Data Access class provides access to data service.
	/// </summary>
	public partial class UserAccessController : DataAccessBase
	{
		#region Initialization

		/// <summary>
		/// Create a DataAccess instance.
		/// </summary>
		public UserAccessController()
		{
		}

		#endregion

		#region Public Members

		#region Constants
#if DEBUG
		public const double InactiveMinutes = 1;
#else
		public const double InactiveMinutes = 5;
#endif
		#endregion

		#region Properties

		/// <summary>
		/// Set connectstring of connection.
		/// </summary>
		/// <value></value>
		public string ConnectString
		{
			get { return base._conn.ConnectionString; }
			set { base._conn.ConnectionString = value; }
		}

		/// <summary>
		/// Contains informations about the login state and the current user.
		/// </summary>
		public LogInData UserData { get; private set; }

		/// <summary>
		/// Get the sqlconnection object.
		/// </summary>
		/// <value></value>
		public SqlConnection SqlConnection
		{
			get { return base._conn; }
		}

		#endregion

		#region Methods

		/// <summary>
		/// Show login form.
		/// </summary>
		/// <returns></returns>
		public DialogResult ShowLoginForm(Guid applicationId)
		{
			FormLogon form = new FormLogon(applicationId);
			form.UserAccess = this;
			return form.ShowDialog();
		}
		/// <summary>
		/// Shows the login form.
		/// </summary>
		/// <param name="owner">The owner.</param>
		/// <param name="title">The title.</param>
		/// <param name="subtitle">The subtitle.</param>
		/// <param name="version">The version.</param>
		/// <returns></returns>
		public DialogResult ShowLoginForm(IWin32Window owner, string title, string subtitle,
			string version, Guid applicationId, EventHandler<NewOrgEventArgs> showCreateNewOrgCallback)
		{
			FormLogon form = new FormLogon(applicationId);
			form.UserAccess = this;
			form.Title = title;
			form.SubTitle = subtitle;
			form.Version = version;
			if ( showCreateNewOrgCallback != null ) {
				form.ShowCreateNewOrganizationForm += showCreateNewOrgCallback;
			}
			DialogResult result = form.ShowDialog(owner);
			if ( showCreateNewOrgCallback != null ) {
				form.ShowCreateNewOrganizationForm -= showCreateNewOrgCallback;
			}
			return result;
		}

		public LogInData LogIn(
			string sLogInName, string sPassWord, int iOrgId, int iLanguageId, string sOrgName, Guid applicationId)
		{
			DataSet ds = execProcedure("login_user",
				createSqlParam("@user_nm", sLogInName),
				createSqlParam("@password", sPassWord),
				createSqlParam("@org_id", iOrgId),
				createSqlParam("@lang_id", iLanguageId),
				createSqlParam("@org_nm", sOrgName),
				createSqlParam("@application_id", applicationId));

			this.UserData = null;
			if ( ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0 ) {
				DataRow row = ds.Tables[0].Rows[0];

				this.UserData = new LogInData();

				this.UserData.ReturnCode = row["return_code"].ToString();
				this.UserData.ReturnMessage = row["return_message"].ToString();

				if ( this.UserData.ReturnCode.Equals("OK") ) {
					this.UserData.UserID = Convert.ToInt32(row["user_id"]);
					this.UserData.LanguageID = (int)row["lang_id"];
					this.UserData.OrganizationID = (int)row["org_id"];
					this.UserData.UserLCID = row.IsNull("user_lcid") ? 0 : (int)row["user_lcid"];
					this.UserData.IsSystemAdministrator = (bool)row["sa_ind"];
					this.UserData.CanUpdate = row.IsNull("can_update_ind") ? true : (bool)row["can_update_ind"];
					this.UserData.UserTimeZoneOffSet = row.IsNull("user_tz_offset") ? 0 : Convert.ToDecimal(row["user_tz_offset"]);
					this.UserData.RealUserTimeZoneOffSet = row.IsNull("real_user_tz_offset") ? 0 : Convert.ToDecimal(row["real_user_tz_offset"]);
					this.UserData.LoginId = (Guid)row["login_id"];
				} else if ( this.UserData.ReturnCode == "USER_IS_LOGGED_IN" ) {
					this.UserData.UserID = Convert.ToInt32(row["user_id"]);
					this.UserData.LoginId = (Guid)row["login_id"];
				}
			}
			return this.UserData;
		}

		public bool RefreshLogIn(LogInData userdata, Guid applicationId)
		{

			execNonQueryProcedure("login_refresh",
				createSqlParam("@user_id", userdata.UserID),
				createSqlParam("@login_id", userdata.LoginId),
				createSqlParam("@application_id", applicationId));

			return true;
		}

		public bool LogOut(LogInData userdata, Guid applicationId)
		{
			DataSet ds = execProcedure("logout_user",
				createSqlParam("@login_id", userdata.LoginId),
				createSqlParam("@application_id", applicationId));

			this.UserData = null;

			return true;
		}

		public bool IsUserActive(int userId, Guid applicationId)
		{
			bool active = false;
			object result = execScalar(
				"SELECT login_time_stamp FROM user_login_log " +
				"WHERE user_id = @user_id AND application_id = @application_id AND " +
					"logout_time_stamp IS NULL",
				createSqlParam("@user_id", userId),
				createSqlParam("@application_id", applicationId));

			if ( result is DateTime ) {
				active = ( (DateTime)result ) > DateTime.Now.AddMinutes(-InactiveMinutes);
			}
			return active;
		}
		#endregion Methods

		#endregion Public Members
	}
}
